import { 
  AmbientLight,
  AxesHelper,
  BoxGeometry,
  Group,
  Mesh,
  MeshPhongMaterial,
  MeshStandardMaterial,
  PerspectiveCamera, 
  PlaneGeometry, 
  Scene, 
  SpotLight, 
  SpotLightHelper, 
  Sprite, 
  SpriteMaterial, 
  Texture, 
  WebGLRenderer
} from "three"
import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls'
import stats from "../../utils/stats"
import { GUI } from 'dat.gui'

const scene = new Scene()
const camera = new PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000)
camera.position.set(0, 150, 150)
camera.lookAt(0, 0, 0)

const renderer = new WebGLRenderer({ antialias: true })
renderer.setClearColor(0x000000)
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement)

const controls = {
  animate: true
}

const ambient = new AmbientLight(0x0c0c0c)
scene.add(ambient)

const spotlight = new SpotLight(0xffffff)
spotlight.position.set(100, 100, 100);
spotlight.castShadow = true;
scene.add(spotlight)
scene.add(new SpotLightHelper(spotlight));

scene.add(new AxesHelper(15));

let floorGeom = new PlaneGeometry(100, 100, 1, 1);
let floorMate = new MeshPhongMaterial({
  color: 0xeeeeee,
});
let floor = new Mesh(floorGeom, floorMate);
floor.rotation.x = Math.PI / -2;
floor.receiveShadow = true;
scene.add(floor);

let group = new Group();
scene.add(group);

let boxGeom = new BoxGeometry(20, 20, 20);
let boxMate = new MeshStandardMaterial({
  color: 0x9999ff,
  // side: BackSide
});
let box = new Mesh(boxGeom, boxMate);
box.position.setY(15);
box.castShadow = true;
group.add(box);

let sprite1 = makeTextSprite(
  '前方',
  {
    fontSize: 24,
    borderColor: '#0099ff',
    backgroundColor: '#ffffff',
  }
);
sprite1.position.set(0, 15, 15);
group.add(sprite1);

let sprite2 = makeTextSprite(
  '这是一个很长很长的文字内容!',
  {
    fontSize: 24,
    borderColor: '#0099ff',
    backgroundColor: '#ffffff',
  }
);
sprite2.position.set(0, 26, 0);
scene.add(sprite2);

const gui = new GUI()
gui.add(controls, 'animate')

const trackballControls = new TrackballControls(camera, renderer.domElement)

function render() {
  stats.update()
  trackballControls.update()

  if (controls.animate) {
    group.rotation.y += 0.01;
  }

  requestAnimationFrame(render)
  renderer.render(scene, camera)
}
render()
interface Parameters {
  fontface?: string,
  fontSize?: number,
  borderThickness?: number,
  borderColor?: string,
  backgroundColor?: string,
}

function makeTextSprite(message: string, parameters: Parameters = {}) {
  let fontface = parameters.hasOwnProperty('fontface') ? parameters.fontface : 'Arial';
  let fontsize = parameters?.fontSize || 18;
  // 边框厚度
  let borderThickness = parameters?.borderThickness || 4;
  let borderColor = parameters?.borderColor || '#ffffff';
  let backgroundColor = parameters?.backgroundColor || '#f5f5f5';
  let dpr = window.devicePixelRatio;

  fontsize *= dpr;

  let canvas = document.createElement('canvas');
  canvas.width = 300 * dpr;
  canvas.height = 150 * dpr;
  canvas.style.position = 'fixed'
  canvas.style.bottom = '0px'
  canvas.style.width = '300px';
  canvas.style.height = '150px';
  let context = canvas.getContext('2d') as CanvasRenderingContext2D;
  // 绽放所有绘制对象,解决canvas不清晰问题
  context.scale(dpr, dpr);

  context.font = `Bold ${fontsize}px ${fontface}`;
  // 获取文字大小
  let metrics = context.measureText(message);
  let textWidth = metrics.width;

  context.fillStyle = backgroundColor;
  context.strokeStyle = borderColor;
  context.lineWidth = borderThickness;

  let w = textWidth + borderThickness * 2;
  w = w > (canvas.width/dpr) ? (canvas.width/dpr) - borderThickness : w;
  roundRect(context, borderThickness/2, borderThickness/2, w, fontsize * 1.4 + borderThickness*2, 6);

  context.fillStyle = 'rgba(0, 0, 0, 1)';
  context.fillText(message, borderThickness, fontsize + borderThickness, 300 - borderThickness*2);

  context.fillStyle = 'rgba(255, 0, 0, .1)'
  context.fillRect(0, 0, canvas.width, canvas.height);

  let texture = new Texture(canvas);
  texture.needsUpdate = true;

  let spriteMater = new SpriteMaterial({
    map: texture,
    // color: 0xff0000,
  });
  let sprite = new Sprite(spriteMater);
  sprite.scale.set(20, 10, 1);
  document.body.appendChild(canvas);
  return sprite;
}

/** 绘制圆角矩形 */
function roundRect(ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, r: number) {
  ctx.beginPath();
  ctx.moveTo(x+r, y);
  ctx.lineTo(x+w-r, y);
  ctx.quadraticCurveTo(x+w, y, x+w, y+r);
  ctx.lineTo(x+w, y+h-r);
  ctx.quadraticCurveTo(x+w, y+h, x+w-r, y+h);
  ctx.lineTo(x+r, y+h);
  ctx.quadraticCurveTo(x, y+h, x, y+h-r);
  ctx.lineTo(x, y+r);
  ctx.quadraticCurveTo(x, y, x+r, y);
  ctx.closePath();
  ctx.fill();
	ctx.stroke(); 
}